﻿#region 作者和版权
/*************************************************************************************
      * CLR 版本:       4.0.30319.225
      * 类 名 称:       IHandler
      * 机器名称:       LIRONGNAN
      * 命名空间:       LCL.MVC
      * 文 件 名:       IHandler
      * 创建时间:       2013 2013-10-13 21:07:24
      * 作    者:       李荣楠
      * 版    权:       IHandler说明：本代码版权归李荣楠所有，请勿商用 2013 - 2014    
      * 修改时间:
      * 修 改 人:
      ************************************************************************************/
#endregion
using System;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using LCL.Common;
using LCL.Config;
using NVelocity;
using NVelocity.App;

namespace LCL.MVC
{
    /// <summary>
    /// 摘要
    /// </summary>
    public class IHandler : IHttpHandler
    {
        #region 方法
        public bool IsReusable
        {
            get
            {
                return true;
            }
        }
        /// <summary>
        /// 通过实现 System.Web.IHttpHandler 接口的自定义 HttpHandler 启用 HTTP Web 请求的处理
        /// 继承自IHttpHandler
        /// </summary>
        /// <param name="context"></param>
        public void ProcessRequest(HttpContext context)
        {
            //刷新静态配置表数据，方便调试而已
            UiConfig.Refresh();

            //获取项目物理根目录
            string physicalApplicationPath = HttpContext.Current.Request.PhysicalApplicationPath;
            //获取请求页面对应的类名
            string classname = Input.GetClassName();
            //获取要访问的实际文件名
            string name = Input.GetWebFileName();
            //获取虚拟应用程序跟路径
            string applicationPath = Input.GetApplicationPath();
            //获取模版
            string skinStyle = UiConfig.Template;

            
            //创建引擎对象
            VelocityContext ctx = new VelocityContext();
            PutBaseConfig(ref ctx);
            IHandlerFactory factory = null;
            try
            {
                //根据类名查找程序集
                factory = (IHandlerFactory)Assembly.Load("LCL").CreateInstance("LCL." + classname, true);
                if (factory == null)
                {
                    name = "404.html";
                    ctx.Put("errorMessage", "找不到页面");
                }
                else
                {
                    //判断是回发页面还是提交页面还是首次加载页面
                    if (!(!(context.Request.HttpMethod == "POST") || this.IsReSubmit(ref context, ref ctx)))
                    {
                        factory.Page_PostBack(ref ctx);
                    }
                    else
                    {
                        factory.Page_Load(ref ctx);
                    }
                }
            }
            catch (InvalidCastException exception)
            {
                name = "500.html";
                ctx.Put("errorMessage", exception.ToString());
                Utils.WriteLogs(exception.ToString());
            }
            catch (Exception exception2)
            {
                name = "500.html";
                ctx.Put("errorMessage", exception2.ToString());
                Utils.WriteLogs(exception2.ToString());
            }
            if (ctx.Get("redirecturl") != null)
            {
                string url = ctx.Get("redirecturl").ToString();
                context.Response.Redirect(url);
            }
            //加载模板文件夹
            VelocityEngine engine = new VelocityEngine();
            engine.SetProperty("resource.loader", "file");
            engine.SetProperty("file.resource.loader.path", physicalApplicationPath + UiConfig.TemplateFolderName + "\\" + skinStyle);
            engine.Init();

            Template template = engine.GetTemplate(name);
            StringWriter writer2 = new StringWriter();
            template.Merge(ctx, writer2);
            context.Response.ContentType = "text/html";
            context.Response.Write(writer2.GetStringBuilder().ToString());
        }
        /// <summary>
        /// 检测是否重复提交
        /// </summary>
        /// <param name="context"></param>
        /// <param name="ctx"></param>
        /// <returns></returns>
        private bool IsReSubmit(ref HttpContext context, ref VelocityContext ctx)
        {
            string str = (context.Request.Cookies["token"] == null) ? string.Empty : context.Request.Cookies["token"].Value;
            StringBuilder builder = new StringBuilder();
            if (context.Request.Files.Count > 0)
            {
                for (int i = 0; i < context.Request.Files.Count; i++)
                {
                    builder.Append(context.Request.Files[i].FileName);
                }
            }
            if (context.Request.Form != null)
            {
                builder.Append(context.Request.Form);
            }
            string str2 = Input.MD5(builder.ToString());
            if (str != str2)
            {
                context.Response.Cookies["token"].Value = str2;
                context.Response.Cookies["token"].Expires = DateTime.Now.AddSeconds(30.0);
                return false;
            }
            context.Response.Cookies["token"].Expires = DateTime.Now.AddSeconds(30.0);
            ctx.Put("errors", "不允许重复提交数据");
            return true;
        }

        /// <summary>
        /// 加载基础数据
        /// </summary>
        /// <param name="ctx"></param>
        private void PutBaseConfig(ref VelocityContext ctx)
        {
            //获取项目物理根目录
            string physicalApplicationPath = HttpContext.Current.Request.PhysicalApplicationPath;

            ctx.Put("WebName", UiConfig.WebName);
            ctx.Put("WebSite", UiConfig.WebSite);
            ctx.Put("copyright", UiConfig.Copyright);
            ctx.Put("keywords", UiConfig.Keywords);
            ctx.Put("exname", UiConfig.ExName);
            ctx.Put("skinstyle", UiConfig.Template);
            ctx.Put("bootpath", "..");
            ctx.Put("webpath", HttpContext.Current.Request.ApplicationPath == "/" ? "" : HttpContext.Current.Request.ApplicationPath);
            ctx.Put("physicalApplicationPath", physicalApplicationPath);
            ctx.Put("templatepath", Input.GetApplicationPath() + "/" + UiConfig.TemplateFolderName + "/" + UiConfig.Template);
            ctx.Put("loginurls", HttpContext.Current.Request.Url);
        }
        #endregion
    }
}